package cn.admin.configcenter.registry.service.client;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.Future;

public class ClientConnectionWorkers {

    private static final ClientConnectionWorker[] clientWorkers;

    public static void dispatch(String clientIp,Runnable task) {

        if (clientIp.contains(":")) {
            (new Exception("illegal clientIp, " + clientIp)).printStackTrace();
            System.exit(0);
        }

        ClientConnectionWorker worker = getWorker(clientIp);
        worker.execute(task);

    }

    private static ClientConnectionWorker getWorker(String clientIp) {
        int idx = clientIp.hashCode() & clientWorkers.length - 1;
        return clientWorkers[idx];
    }

    public static <V> List<Future<V>> dispatchToAllWorkers(Callable<V> task) {

        List<Future<V>> futures = new ArrayList<>(clientWorkers.length);
        for (ClientConnectionWorker clientConnectionWorker : clientWorkers) {
            futures.add(clientConnectionWorker.execute(task));
        }

        return futures;

    }

    static {
        int coreCount = Runtime.getRuntime().availableProcessors();
        int workerCount;
        for (workerCount = 1;workerCount < coreCount * 2;workerCount <<= 1) {
            ;
        }

        clientWorkers = new ClientConnectionWorker[workerCount];

        for (int mod = 0;mod < workerCount; ++mod) {
            clientWorkers[mod] = new ClientConnectionWorker(mod,workerCount);
        }
    }

}
